package cn.kailangtu.myapplication.data;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.SystemClock;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import com.alibaba.fastjson.JSONObject;
import org.greenrobot.eventbus.EventBus;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import cn.kailangtu.myapplication.R;
import cn.kailangtu.myapplication.data.specialview.BaseSpecialView;
import cn.kailangtu.myapplication.data.specialview.ElectricView;
import cn.kailangtu.myapplication.events.PageRefreshEvent;
import cn.kailangtu.myapplication.tools.Odometer;

public class CanDataManager {

    Map<Integer,byte[]> container ;
    List<Integer> containerView;
    Map<Integer,List<CanDataItem>> pageViews;
    Map<String,CanDataItem> specialView;
    List<Integer> ls时间控件 = new ArrayList<>();
    List<BaseSpecialView> ls特殊控件 =new ArrayList<>();
    Odometer odometer;

    private static CanDataManager instance;
    public static CanDataManager getInstance()
    {
        if(instance == null)
        {
            instance = new CanDataManager();
        }
        return instance;
    }
    private CanDataManager(){
        container = new ConcurrentHashMap<>();
        pageViews = new HashMap<>();
        containerView = new ArrayList<>();
        specialView = new HashMap<>();
        odometer = new Odometer();

        containerView.add(R.id.llPage0);

        ls时间控件.add(R.id.tvDate);
        ls时间控件.add(R.id.tvTime);
        ls时间控件.add(R.id.tvMainTime);

        ls特殊控件.add(ElectricView.getInstance());

        PageRefresh();
    }


    public synchronized void addNewControler(Activity context,int pageId)
    {
        //把所有容器都加进来
        if(!containerView.contains(pageId)) {
            containerView.add(pageId);
            buildSub(context);
        }
    }


    public void setNewValue(int frame,byte[] data)
    {
        byte[] value = null;
        if(container.containsKey(frame))
        {
            value = container.get(frame);
        }
        else{
            value = new byte[8];
            container.put(frame,value);
        }
        if(data.length >=8)
        {
            System.arraycopy(data,0,value,0,8);
        }
        else
        {
            System.arraycopy(data,0,value,0,data.length);
        }
    }

    public  void buildSub(Activity context)
    {

        for(Integer vGroupId : containerView){

            if(!pageViews.containsKey(vGroupId)) {
                ViewGroup vGroup = context.findViewById(vGroupId);
                List<View> lsChildren = new ArrayList<>();
                getAllChild(vGroup, lsChildren);
                Log.d("GETALLCHILD", "共找到:" + lsChildren.size());
                List<CanDataItem> lsViews = new ArrayList<>();
                pageViews.put(vGroup.getId(), lsViews);
                for (int i = 0; i < lsChildren.size(); i++) {
                    View vChild = lsChildren.get(i);
                    String vStringId = vChild.getResources().getResourceEntryName(vChild.getId()).toUpperCase();
                    String vTag = vChild.getTag() == null ? "" : vChild.getTag().toString().toUpperCase();
                    Log.d("SHOOTLEE", "资源ID:" + vStringId);

                    //
                    if (vStringId.indexOf("CAN") > -1) {

                        CanDataItem newCanData = build(vChild.getId(), vStringId, vTag);
                        lsViews.add(newCanData);

                    }
                }
            }
        }

    }

    public  void buildMain(Activity context)
    {

        for(Integer vGroupId : containerView){

            ViewGroup vGroup = context.findViewById(vGroupId);
            List<View> lsChildren = new ArrayList<>();
            getAllChild(vGroup,lsChildren);
            Log.d("GETALLCHILD", "共找到:" + lsChildren.size());
            List<CanDataItem> lsViews = new ArrayList<>();
            pageViews.put(vGroup.getId(),lsViews);
            for(int i= 0;i< lsChildren.size();i++)
            {
                View vChild = lsChildren.get(i);
                String vStringId = vChild.getResources().getResourceEntryName(vChild.getId()).toUpperCase();
                String vTag =  vChild.getTag() == null?"":vChild.getTag().toString().toUpperCase();
                Log.d("SHOOTLEE","资源ID:"+vStringId);

                //
                if(vStringId.indexOf("CAN") > -1) {

                    CanDataItem newCanData = build(vChild.getId(),vStringId,vTag);
                    lsViews.add(newCanData);

                }
            }
        }

        for(BaseSpecialView baseSpecialView : ls特殊控件)
        {
            if(pageViews.containsKey(baseSpecialView.getPage()))
            {
                List<CanDataItem> lsCanDataItem =  pageViews.get(baseSpecialView.getPage());
                lsCanDataItem.add(buildBySpecialView(baseSpecialView));
            }
        }
    }

    public  void build(Activity context)
    {

        for(Integer vGroupId : containerView){

            ViewGroup vGroup = context.findViewById(vGroupId);
            List<View> lsChildren = new ArrayList<>();
            getAllChild(vGroup,lsChildren);
            Log.d("GETALLCHILD", "共找到:" + lsChildren.size());
            List<CanDataItem> lsViews = new ArrayList<>();
            pageViews.put(vGroup.getId(),lsViews);
            for(int i= 0;i< lsChildren.size();i++)
            {
                View vChild = lsChildren.get(i);
                String vStringId = vChild.getResources().getResourceEntryName(vChild.getId()).toUpperCase();
                String vTag =  vChild.getTag() == null?"":vChild.getTag().toString().toUpperCase();
                Log.d("SHOOTLEE","资源ID:"+vStringId);

                //
                if(vStringId.indexOf("CAN") > -1) {

                    CanDataItem newCanData = build(vChild.getId(),vStringId,vTag);
                    lsViews.add(newCanData);

                }
            }
        }

        for(BaseSpecialView baseSpecialView : ls特殊控件)
        {
            if(pageViews.containsKey(baseSpecialView.getPage()))
            {
                List<CanDataItem> lsCanDataItem =  pageViews.get(baseSpecialView.getPage());
                lsCanDataItem.add(buildBySpecialView(baseSpecialView));
            }
        }
    }

    public byte[] getData(int frame)
    {
        if(container.containsKey(frame))
        {
            return container.get(frame);
        }
        else{
            byte[] newData =  new byte[8];
            container.put(frame,newData);
            return newData;
        }

    }



    @SuppressLint("ResourceType")
    private void getAllChild(ViewGroup viewGroup, List<View> container)
    {
        //Log.d("GETALLCHILD","VIEWGROUP_ID:"+viewGroup.getId());
        int childCount = viewGroup.getChildCount();
        if(childCount >0)
        {
            for(int i=0;i< childCount;i++){
                View vChild = viewGroup.getChildAt(i);
                if(vChild instanceof ViewGroup)
                {
                    getAllChild((ViewGroup)vChild,container);
                }
                else
                {
                    if(vChild.getId() > 0) {
                        Log.d("GETALLCHILD", "添加新VIEW:" + vChild.getId());
                        container.add(vChild);
                    }
                }
            }
        }
    }


    public void RefreshView(int id,Activity context)
    {
        if(pageViews.containsKey(id))
        {
            List<CanDataItem> lsItem = pageViews.get(id);
            Log.d("TESTTEST","SET NEW COUNT:"+lsItem.size());
            for(CanDataItem item : lsItem){
                item.resetView(context);
            }
        }
        计算总里程();
    }


    private void PageRefresh()
    {
        new Thread(new Runnable() {
            @Override
            public void run() {
                //刷新页面,每300秒刷新一次
                while(true){
                    EventBus.getDefault().post(new PageRefreshEvent());
                    SystemClock.sleep(300);
                }
            }
        }).start();
    }




    public void test(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                //刷新数据
                int index = 255;
                SystemClock.sleep(10000);
                while(true) {
                    Log.d("TESTTEST","KEY COUNT:"+container.keySet().size());
                    index--;
                    if(index <= 0)
                    {
                        index = 255;
                    }
                    for (Integer key : container.keySet()) {

                        byte[] currData = container.get(key);
                        for(int i = 0;i<currData.length;i++){
                            currData[i] = (byte)index;
                            Log.d("NEWVALUE",""+currData[i]);
                        }
                    }
                    SystemClock.sleep(1000);
                }
            }
        }).start();
    }

    public List<Integer> getLs时间控件() {
        return ls时间控件;
    }

    public void setLs时间控件(List<Integer> ls时间控件) {
        this.ls时间控件 = ls时间控件;
    }



    public Float getValueByCanID(String canID)
    {
        Log.d("SHOOTLEE_TOTAL","进来了，ID:"+canID);
        CanDataItem canDataItem = null;
        if(specialView.containsKey(canID))
        {
            canDataItem = specialView.get(canID);

        }
        else
        {
            canDataItem = build(null,canID);
            specialView.put(canID,canDataItem);
        }
        Float result = canDataItem.getFloatValue();
        Log.d("SHOOTLEE_TOTAL","进来了，结果:"+result);
        return result;
    }

    String CANID_速度 = "CAN08F200A0H5P_50";
    public void 计算总里程()
    {
        Float newSpeed = getValueByCanID(CANID_速度);
        if(newSpeed>0) {
            odometer.updateSpeed(newSpeed, System.currentTimeMillis());
        }
    }

    public String get总里程()
    {
        return odometer.getTotalDistanceString();
    }


    public CanDataItem buildBySpecialView(BaseSpecialView baseSpecialView)
    {
        CanID canId =   CanID.build(baseSpecialView.getCanID());
        CanDataItem newCanData = new CanDataItem();
        newCanData.setAddress(canId.get地址());
        newCanData.setDataIndex(canId.get数据索引下标());
        newCanData.setByteCount(canId.get数据长度());
        newCanData.setJingdu(canId.get精度());
        newCanData.setBitIndex(canId.get比特位());
        newCanData.setPianyi(canId.get偏移量());
        newCanData.setSpecialView(baseSpecialView);
        newCanData.setHighPosition(canId.get高位位置());
        newCanData.setMinValue(canId.get最小值());
        return newCanData;
    }

    public CanDataItem build(Integer viewId,String canID)
    {
        return build(viewId,canID,null);
    }
    public CanDataItem build(Integer viewId,String canID,String tag)
    {
           /*
                    ID规范，处理数据， 主要解决绑定哪个地址的哪个数据，如果有BIT，对应哪个BIT，如果有精度，处理精度
                    元素：CAN,H,S,J,P,前缀
                    CAN代表是CAN协议的数据
                    H表示结应的字节
                    S对应的BIT位置，但不是必须的
                    J代表精度，但也不是必须的
                    P代表偏移量，P_40代表-40，P_0.1代表-0.1，P10代表10
                    前缀，可以加到CAN前面，防止元素用一样的地址数据时，命名重复

                    CAN465H0:ID为465，字节为第1个（下标0）
                    CAN465H01:ID为465，字节为第0加第1
                    CAN465H0S0:ID为465，字节为第1个（下标0）比特为第1个（下标0），
                    CAN465H01J0.01:ID为465，字节为第0加第1，精度为0.01

                 */
        CanID canId = CanID.build(canID);
        CanDataItem newCanData = new CanDataItem();
        newCanData.setAddress(canId.get地址());
        newCanData.setDataIndex(canId.get数据索引下标());
        newCanData.setByteCount(canId.get数据长度());
        newCanData.setJingdu(canId.get精度());
        newCanData.setBitIndex(canId.get比特位());
        newCanData.setPianyi(canId.get偏移量());
        newCanData.setView(viewId);
        newCanData.setHighPosition(canId.get高位位置());
        newCanData.setMinValue(canId.get最小值());



           /*
                                vTag规范，主要定义是数据值对于View产生什么动作
                                元素：A,S,U,V,R
                                A打头，A是动作的意思，对应ActionCode.java里的动作枚举，，
                                S集合，对应CanDataItemSet里的集合 A是图片，S集合就到图片里去找
                                U单位
                                A1: 设置值，代表设置文本，最基础的，如果不设置，默认值就是A1
                                A2S1：A2代表改图片，S1是去图片集合里找第一个集合
                             */

        if(tag != null && !tag.isEmpty()) {

            CanTAG canTAG = CanTAG.build(tag);
            newCanData.setLs_文字集合(canTAG.getLs_文字集合());
            newCanData.setActionCode(canTAG.getActionCode());
            newCanData.setUnit(canTAG.get单位());
            newCanData.setLs_显示(canTAG.getLs_显示());
            newCanData.setLs_颜色集合(canTAG.getLs_颜色集合());
            newCanData.setLs_图片集合(canTAG.getLs_图片集合());
            newCanData.setRefreshMode(canTAG.get刷新模式());
            newCanData.setLs_自定义(canTAG.getLs_自定义());
            newCanData.setLs_值匹配(canTAG.getLs_值匹配());
            newCanData.set对比值(canTAG.get对比值());
            newCanData.setLs_声音(canTAG.getLs_声音());

        }

        return newCanData;
    }

    public void clean清空里程()
    {
        odometer.reset();
    }
}
